package filter;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * CollectionsFilter - You have to write your own filter, extending this
 * Filter<T>. Example:<br>
 * <code>
 * 	public class NameFilter extends Filter<SomeObject> {
	
	private final String name;
	
	public NameFilter(String name) {
		this.name = name;
	}
 * 
 * @Override protected boolean matchesCriteria(SomeObject object) { return
 *           object.getName().equals(name); 
 *  }
 * 
 *  } </code>
 *           
 *  Usage-Example:
 *  <code>
 *  	NameFilter martinfilter = new NameFilter("Martin");
		NameFilter susifilter = new NameFilter("Susi");
		Collection<SomeObject> filteredCollection = (martinfilter.or(susifilter.not())).not().filter(collection);
 *  </code>
 *  
 * 
 * @author martin.lemanski
 * 
 * @param <T>
 *            T is the object you want to Filter.
 */
public abstract class Filter<T> {

	protected abstract boolean matchesCriteria(T object);

	public FilterExpression<T> and(Filter<T> andFilter) {
		return new AndFilterExpression<T>().addFilter(this, andFilter);
	}

	public FilterExpression<T> or(Filter<T> orFilter) {
		return new OrFilterExpression<T>().addFilter(this, orFilter);
	}

	public FilterExpression<T> not() {
		return new NotFilterExpression<T>().addFilter(this);
	}

	public Collection<T> filter(Collection<T> coll) {
		Set<T> filteredList = new HashSet<T>();

		for (T item : coll) {
			if (this.matchesCriteria(item)) {
				filteredList.add(item);
			}
		}

		return filteredList;
	}
}